#include "TEventLoop.h"
#include "TServer.h"
#include "TSocket.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>

#ifdef WIN32
TEventLoop::TEventLoop()
{
    FD_ZERO(&connSet_);
}

TEventLoop::~TEventLoop()
{

}

bool TEventLoop::AddLoop(TSocket* sock)
{
    std::cout << "threadid[" << std::this_thread::get_id() << "] addLoop, because sockfd " << sock->fd() << std::endl;
    FD_SET(sock->fd(), &connSet_);
    cliMap[sock->fd()] = sock;
    return true;
}

bool TEventLoop::DelLoop(TSocket* sock)
{
    std::cout << "threadid[" << std::this_thread::get_id() << "] delLoop, because sockfd " << sock->fd() << std::endl;
    FD_CLR(sock->fd(), &connSet_);
    return true;
}

void TEventLoop::RunLoop(TServer* server)
{
    for (;;)
    {
        FD_ZERO(&sendSet_);
        FD_ZERO(&recvSet_);
        sendSet_ = connSet_;
        recvSet_ = connSet_;
        int ret = ::select(0, &recvSet_, /*&sendSet_*/NULL, NULL, NULL);
		if (-1 == ret) { ::Sleep(1000); continue; }
        for (int i=0; i<connSet_.fd_count; i++)
        {
            if (FD_ISSET(connSet_.fd_array[i], &recvSet_))
            {
				server->PreRecv(cliMap[connSet_.fd_array[i]]);
            }
        }
    }
}

#else
TEventLoop::TEventLoop()
{
    epollfd_ = epoll_create(MAX_EVENTS);
    if (epollfd_ < 0)
    {
        printf("epoll_create出错, exit");
        exit(0);
    }
}

TEventLoop::~TEventLoop()
{
    //close(epollfd_);
}

bool TEventLoop::AddLoop(TSocket* sock)
{
    ev_.events = EPOLLIN;
    ev_.data.ptr = sock;
    if (-1 == ::epoll_ctl(epollfd_, EPOLL_CTL_ADD, sock->fd(), &ev_))
    {
        printf("epoll_ctl出错, exit");
        exit(0);
    }
}

bool TEventLoop::DelLoop(TSocket* sock)
{
    ev_.events = EPOLLIN;
    ev_.data.ptr = sock;
    if (-1 == ::epoll_ctl(epollfd_, EPOLL_CTL_DEL, sock->fd(), &ev_))
    {
        printf("epoll_ctl出错, exit");
        exit(0);
    }
}

void TEventLoop::RunLoop(TServer* server)
{
    for (;;)
    {
        int fds = ::epoll_wait(epollfd_, events_, MAX_EVENTS, -1);
        for (int i=0; i<fds; i++)
        {
            if (events_[i].events & EPOLLIN)
            {
                //printf("events.ptr->fd(): %d, server.serSock_.fd(): %d\n", ((TSocket*)events[i].data.ptr)->fd(), server->serSock_.fd());
                TSocket* sock = (TSocket*)events_[i].data.ptr;
                server->PreRecv(sock);
            }
            else
            {

            }
        }
    }
}


#endif